package com.smartbus.bus.controller;

import com.smartbus.bus.service.TextToSpeechService;
import com.smartbus.bus.service.impl.TextToSpeechServiceImpl;
import com.smartbus.bus.service.IBusStationsService;
import com.smartbus.bus.domain.BusStations;
import com.smartbus.common.annotation.Log;
import com.smartbus.common.core.controller.BaseController;
import com.smartbus.common.core.domain.AjaxResult;
import com.smartbus.common.enums.BusinessType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;

/**
 * 文本转语音控制器
 *
 * @author smartbus
 * @date 2024-09-24
 */
@Api(tags = "文本转语音管理")
@RestController
@RequestMapping("/bus/tts")
public class TextToSpeechController extends BaseController {

    @Autowired
    private TextToSpeechService textToSpeechService;

    @Autowired
    private IBusStationsService busStationsService;

    @Autowired
    private HttpServletRequest request;

    /**
     * 转换文件路径为静态资源访问路径
     * @param filePath 相对文件路径，如：/voice/filename.mp3
     * @return 静态资源访问路径，如：/profile/upload/voice/filename.mp3
     */
    private String convertToStaticUrl(String filePath) {
        if (filePath == null || filePath.trim().isEmpty()) {
            return filePath;
        }

        // 如果已经是完整的静态资源路径，直接返回
        if (filePath.startsWith("/profile/")) {
            return filePath;
        }

        // 构建静态资源访问路径：/profile/upload + filePath
        // filePath 格式为 /voice/filename.mp3
        // 最终路径为 /profile/upload/voice/filename.mp3
        return "/profile/upload" + filePath;
    }

    /**
     * 转换静态资源访问路径为实际文件系统路径
     * @param staticUrl 静态资源访问路径，如：/profile/upload/voice/filename.mp3
     * @return 实际文件系统路径，如：/upload/voice/filename.mp3
     */
    private String convertStaticUrlToFilePath(String staticUrl) {
        if (staticUrl == null || staticUrl.trim().isEmpty()) {
            return staticUrl;
        }

        // 如果是静态资源访问路径，去掉 /profile 前缀
        if (staticUrl.startsWith("/profile/upload")) {
            return staticUrl.substring("/profile".length()); // 返回 /upload/voice/filename.mp3
        }

        // 如果已经是文件系统路径，直接返回
        return staticUrl;
    }

    /**
     * 文本转语音
     */
    @ApiOperation("文本转语音")
    @Log(title = "文本转语音", businessType = BusinessType.OTHER)
    @PostMapping("/generate")
    public AjaxResult generateSpeech(
            @ApiParam("要转换的文本") @RequestParam String text,
            @ApiParam("站点ID") @RequestParam Long stationId,
            @ApiParam("语音类型") @RequestParam(required = false) String voiceType,
            @ApiParam("语速(0-15)") @RequestParam(required = false) Integer speed,
            @ApiParam("音调(0-15)") @RequestParam(required = false) Integer pitch,
            @ApiParam("音量(0-15)") @RequestParam(required = false) Integer volume) {

        if (text == null || text.trim().isEmpty()) {
            return error("文本内容不能为空");
        }

        if (stationId == null) {
            return error("站点ID不能为空");
        }

        try {
            // 验证站点是否存在
            BusStations station = busStationsService.selectBusStationsById(stationId);
            if (station == null) {
                return error("指定的站点不存在：" + stationId);
            }

            // 使用站点相关的语音生成方法，播报类型设为通用类型
            if (textToSpeechService instanceof TextToSpeechServiceImpl) {
                TextToSpeechServiceImpl ttsImpl = (TextToSpeechServiceImpl) textToSpeechService;
                String filePath = ttsImpl.generateStationVoice(stationId, text, "custom",
                                                              voiceType, speed, pitch, volume);
                if (filePath != null) {
                    String staticUrl = convertToStaticUrl(filePath);
                    return success("语音生成成功", staticUrl);
                } else {
                    return error("语音生成失败，请检查配置或稍后重试");
                }
            } else {
                return error("语音服务不可用");
            }

        } catch (Exception e) {
            logger.error("语音生成失败：" + e.getMessage(), e);
            return error("语音生成失败：" + e.getMessage());
        }
    }

    /**
     * 文本转语音（使用默认参数）
     */
    @ApiOperation("文本转语音(默认参数)")
    @Log(title = "文本转语音", businessType = BusinessType.OTHER)
    @PostMapping("/generate/default")
    public AjaxResult generateSpeechDefault(@ApiParam("要转换的文本") @RequestParam String text) {

        if (text == null || text.trim().isEmpty()) {
            return error("文本内容不能为空");
        }

        try {
            String filePath = textToSpeechService.textToSpeech(text);
            if (filePath != null) {
                String staticUrl = convertToStaticUrl(filePath);
                return success("语音生成成功", staticUrl);
            } else {
                return error("语音生成失败，请检查配置或稍后重试");
            }
        } catch (Exception e) {
            logger.error("语音生成失败：" + e.getMessage(), e);
            return error("语音生成失败：" + e.getMessage());
        }
    }

    /**
     * 获取语音配置信息
     */
    @ApiOperation("获取语音配置")
    @GetMapping("/config")
    public AjaxResult getVoiceConfig() {
        try {
            Map<String, Object> config = textToSpeechService.getVoiceConfig();
            return success(config);
        } catch (Exception e) {
            logger.error("获取语音配置失败：" + e.getMessage(), e);
            return error("获取语音配置失败：" + e.getMessage());
        }
    }

    /**
     * 删除语音文件（仅标记数据库记录为不活跃）
     */
    @ApiOperation("删除语音文件")
    @Log(title = "删除语音文件", businessType = BusinessType.DELETE)
    @DeleteMapping("/file")
    public AjaxResult deleteVoiceFile(@ApiParam("文件路径") @RequestParam String filePath) {

        if (filePath == null || filePath.trim().isEmpty()) {
            return error("文件路径不能为空");
        }

        try {
            // 转换静态资源访问路径为原始文件路径用于数据库查询
            String originalFilePath = convertStaticUrlToFilePath(filePath);

            // 通过文件路径查找数据库记录并标记为不活跃
            if (textToSpeechService instanceof TextToSpeechServiceImpl) {
                TextToSpeechServiceImpl ttsImpl = (TextToSpeechServiceImpl) textToSpeechService;
                boolean success = ttsImpl.markVoiceFileAsInactive(originalFilePath);
                if (success) {
                    return AjaxResult.success("语音文件删除成功");
                } else {
                    return error("文件删除失败，文件记录不存在");
                }
            } else {
                return error("语音服务不可用");
            }
        } catch (Exception e) {
            logger.error("删除语音文件失败：" + e.getMessage(), e);
            return error("删除语音文件失败：" + e.getMessage());
        }
    }

    /**
     * 清理过期语音文件
     */
    @ApiOperation("清理过期语音文件")
    @Log(title = "清理过期语音文件", businessType = BusinessType.CLEAN)
    @PostMapping("/clean")
    public AjaxResult cleanExpiredFiles(@ApiParam("过期天数") @RequestParam(defaultValue = "7") int days) {

        if (days < 1) {
            return error("过期天数必须大于0");
        }

        try {
            int count = textToSpeechService.cleanExpiredVoiceFiles(days);
            return success("清理完成，共清理了" + count + "个过期文件");
        } catch (Exception e) {
            logger.error("清理过期文件失败：" + e.getMessage(), e);
            return error("清理过期文件失败：" + e.getMessage());
        }
    }

    /**
     * 生成站点播报语音
     */
    @ApiOperation("生成站点播报语音")
    @Log(title = "站点播报语音", businessType = BusinessType.OTHER)
    @PostMapping("/station")
    public AjaxResult generateStationAnnouncement(
            @ApiParam("站点名称") @RequestParam String stationName,
            @ApiParam("播报类型：arrival(到站), departure(发车), next(下一站)") @RequestParam String announcementType) {

        if (stationName == null || stationName.trim().isEmpty()) {
            return error("站点名称不能为空");
        }

        try {
            // 根据站点名称查找站点信息
            BusStations queryStation = new BusStations();
            queryStation.setStationName(stationName);
            List<BusStations> stations = busStationsService.selectBusStationsList(queryStation);

            if (stations.isEmpty()) {
                return error("未找到指定的站点：" + stationName);
            }

            BusStations station = stations.get(0);
            Long stationId = station.getId();

            String text;
            switch (announcementType) {
                case "arrival":
                    text = "列车即将到达" + stationName + "站，请准备下车";
                    break;
                case "departure":
                    text = "列车即将从" + stationName + "站发车，请注意安全";
                    break;
                case "next":
                    text = "下一站：" + stationName;
                    break;
                default:
                    return error("播报类型不正确，支持：arrival、departure、next");
            }

            // 使用新的方法生成语音并保存到数据库
            if (textToSpeechService instanceof TextToSpeechServiceImpl) {
                TextToSpeechServiceImpl ttsImpl = (TextToSpeechServiceImpl) textToSpeechService;
                String filePath = ttsImpl.generateStationVoice(stationId, text, announcementType,
                                                              "1", 5, 5, 8);
                if (filePath != null) {
                    String staticUrl = convertToStaticUrl(filePath);
                    return success("站点播报语音生成成功", staticUrl);
                } else {
                    return error("语音生成失败，请检查配置或稍后重试");
                }
            } else {
                // 降级到原来的方法
                String filePath = textToSpeechService.textToSpeech(text);
                if (filePath != null) {
                    String staticUrl = convertToStaticUrl(filePath);
                    return success("站点播报语音生成成功", staticUrl);
                } else {
                    return error("语音生成失败，请检查配置或稍后重试");
                }
            }

        } catch (Exception e) {
            logger.error("生成站点播报语音失败：" + e.getMessage(), e);
            return error("生成站点播报语音失败：" + e.getMessage());
        }
    }
}
